/*
 * @Author       : Xu Xiaokang
 * @Email        :
 * @Date         : 2025-04-24 22:04:45
 * @LastEditors  : Xu Xiaokang
 * @LastEditTime : 2025-05-18 00:06:44
 * @Filename     :
 * @Description  :
*/

/*
! 模块功能: RAM顶层文件, 实例化自编RAM与Vivado的BRAM IP，此模块用于冲突测试
* 思路:
* 1.因为仅作为冲突测试，为保证简单性，不使用en信号，也不使用初始化文件和输出寄存器
* 2.仅做同步时钟的冲突测试，异步时钟没有测试的必要，所以Vivado RAM IP要勾选Common Clock
* 3.仅做TDPRAM即真双口RAM的冲突测试，其它类型的RAM没有写-写冲突，仅SDRRAM存在读-写冲突但也比较好理解
~ 注意:
~ 1.
% 其它
*/

`default_nettype none

module myTDPRAM_Top_collision
#(
  parameter RAM_STYLE = "block", //* RAM类型, 可选"block"(默认), "distributed"
  parameter DATA_WIDTH = 8, //* 数据位宽, 可选1, 2, 3, ..., 默认为8
  parameter ADDR_WIDTH = 6, //* RAM地址位宽, 对应RAM深度, 可选1, 2, 3, ..., 默认为6, 对应深度2**6=64
  parameter OPERATING_MODE_A = "WF", //* 可选"Write First"(默认), "Read First", "No Change"
  parameter OPERATING_MODE_B = "WF", //* 可选"Write First"(默认), "Read First", "No Change"
  parameter [0:0] USE_ENA = 0, //* 启用ENA信号
  parameter [0:0] USE_ENB = 0, //* 启用ENB信号
  parameter [1:0] OUTPUT_REG_NUM = 0, //* 可选0(默认), 1, 2
  parameter INIT_FILE = "", //* 初始化文件名，空(默认)表示不初始化，示例目录C:\_myJGY\ram_init.coe
  /*
  * 默认初始值, 在未指定初始化文件或初始化文件行数比RAM深度小时起作用, 使用16进制表示, 默认值0,
  * 对应Vivado BRAM IP的功能Fill Remaining Memory Locations
  */
  parameter [DATA_WIDTH-1:0] INIT_VALUE_HEX = 'h0
)(
  input  wire                   clka,  //* A端口时钟
  input  wire                   ena,   //* A端口操作使能
  input  wire                   wea,   //* A端口写使能
  input  wire [ADDR_WIDTH-1:0]  addra, //* A端口读/写地址
  input  wire [DATA_WIDTH-1:0]  dina,  //* A端口输入数据
  output wire [DATA_WIDTH-1:0]  douta, //* A端口输出数据
  output wire [DATA_WIDTH-1:0]  vivado_douta, //* A端口输出数据

  input  wire                   clkb,  //* B端口时钟
  input  wire                   enb,   //* B端口操作使能
  input  wire                   web,   //* B端口写使能
  input  wire [ADDR_WIDTH-1:0]  addrb, //* B端口读/写地址
  input  wire [DATA_WIDTH-1:0]  dinb,  //* B端口输入数据
  output wire [DATA_WIDTH-1:0]  doutb, //* B端口输出数据
  output wire [DATA_WIDTH-1:0]  vivado_doutb  //* B端口输出数据
);


//++ 实例化Vivado RAM IP ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
blk_mem_gen_0 your_instance_name (
  .clka  (clka ), // input wire clka
  .wea   (wea  ), // input wire [0  : 0] wea
  .addra (addra), // input wire [3  : 0] addra
  .dina  (dina ), // input wire [15 : 0] dina
  .douta (vivado_douta), // output wire [15: 0] douta
  .clkb  (clkb ), // input wire clkb
  .web   (web  ), // input wire [0  : 0] web
  .addrb (addrb), // input wire [3  : 0] addrb
  .dinb  (dinb ), // input wire [15 : 0] dinb
  .doutb (vivado_doutb)// output wire [15 : 0] doutb
);
//-- 实例化Vivado RAM IP ------------------------------------------------------------


//++ 实例化自编RAM IP ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
myTDPRAM #(
  .RAM_STYLE        (RAM_STYLE       ),
  .DATA_WIDTH       (DATA_WIDTH      ),
  .ADDR_WIDTH       (ADDR_WIDTH      ),
  .OPERATING_MODE_A (OPERATING_MODE_A),
  .OPERATING_MODE_B (OPERATING_MODE_B),
  .USE_ENA          (USE_ENA         ),
  .USE_ENB          (USE_ENB         ),
  .OUTPUT_REG_NUM   (OUTPUT_REG_NUM  ),
  .INIT_FILE        (INIT_FILE       ),
  .INIT_VALUE_HEX   (INIT_VALUE_HEX  )
) myTDPRAM_inst (
  .clka  (clka ),
  .ena   (ena  ),
  .wea   (wea  ),
  .dina  (dina ),
  .addra (addra),
  .douta (douta),
  .clkb  (clkb ),
  .enb   (enb  ),
  .web   (web  ),
  .dinb  (dinb ),
  .addrb (addrb),
  .doutb (doutb)
);
//-- 实例化自编RAM IP ------------------------------------------------------------


endmodule
`resetall